package com.kongjs.common.datasource.factory;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.kongjs.common.datasource.properties.DataSourceProperties;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.sql.DataSource;

public class DataSourceFactory {
    public static DataSource createDatasource(DataSourceProperties dataSourceProperties) {
        Assert.notNull(dataSourceProperties, "dataSourceProperties must not be null");
        Assert.hasText(dataSourceProperties.getType(), "dataSourceType must not be empty");
        Assert.hasText(dataSourceProperties.getDriverClassName(), "driverClassName must not be empty");
        Assert.hasText(dataSourceProperties.getUrl(), "url must not be empty");
        Assert.hasText(dataSourceProperties.getUsername(), "username must not be empty");
        Assert.hasText(dataSourceProperties.getPassword(), "password must not be empty");
        if (StringUtils.hasText(dataSourceProperties.getType())) {
            Class<?> type;
            try {
                type = Class.forName(dataSourceProperties.getType());
            } catch (ClassNotFoundException e) {
                throw new RuntimeException("数据源类型不存在", e);
            }
            Assert.isAssignable(DataSource.class, type, "数据源类型错误");
            if (type.isAssignableFrom(HikariDataSource.class)) {
                try {
                    HikariConfig hikariConfig = new HikariConfig();
                    hikariConfig.setDriverClassName(dataSourceProperties.getDriverClassName());
                    hikariConfig.setJdbcUrl(dataSourceProperties.getUrl());
                    hikariConfig.setUsername(dataSourceProperties.getUsername());
                    hikariConfig.setPassword(dataSourceProperties.getPassword());
                    hikariConfig.setDataSourceProperties(dataSourceProperties);
                    return new HikariDataSource(hikariConfig);
                } catch (Exception e) {
                    throw new RuntimeException("HikariDataSource创建数据源异常", e);
                }
            }
            if (type.isAssignableFrom(DruidDataSource.class)) {
                try {
                    DruidDataSource druidDataSource = new DruidDataSource();
                    druidDataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
                    druidDataSource.setUrl(dataSourceProperties.getUrl());
                    druidDataSource.setUsername(dataSourceProperties.getUsername());
                    druidDataSource.setPassword(dataSourceProperties.getPassword());
                    DruidDataSourceFactory.config(druidDataSource, dataSourceProperties);
                    return druidDataSource;
                } catch (Exception e) {
                    throw new RuntimeException("DruidDataSource创建数据源异常", e);
                }
            }
        }
        throw new RuntimeException("数据源类型暂不支持");
    }
}
